import asyncio
from enum import Enum

from loguru import logger

from com.arcfox.util import async_request as requests, constant
from com.arcfox.util.util import print_cost_time, random_useragent


class ExecuteType(Enum):
    # 执行一次
    ONCE = 1
    # 永久执行
    PERMANENT = 2
    # 任务执行完结束
    FINISH = 3


class BaseSpider:

    def __init__(self):
        self.name = self.__class__.__name__
        self.session = None

    def get_name(self):
        if not hasattr(self, "name"):
            self.__setattr__("name", self.__class__.__name__)
        return self.name

    async def init_session(self):
        if not self.session:
            self.session = await requests.session()

    async def init_data_version(self, client):
        pass

    async def close_session(self):
        if hasattr(self, "session") and self.session:
            logger.info(f"[{self.get_name()}]任务结束, 释放session")
            await self.session.close()

    def get_default_header(self, random_ua=False):
        default_ua = constant.DEFAULT_USER_AGENT
        return {
            "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
            "Accept-Encoding": "gzip, deflate, br",
            "Accept-Language": "zh-CN,zh;q=0.9",
            "Cache-Control": "no-cache",
            "Connection": "keep-alive",
            "User-Agent": random_useragent() if random_ua else default_ua
        }

    async def _pull_task(self):
        pass

    @print_cost_time
    async def start_crawl(self):
        await self.init_data_version()
        while True:
            task, execute_type = await self._pull_task()
            if execute_type == ExecuteType.ONCE:
                await self._crawl_by_task(task)
                logger.info(f"[{self.get_name()}]任务执行一次, 结束爬虫")
                break
            elif execute_type == ExecuteType.FINISH:
                if not task:
                    logger.info(f"[{self.get_name()}]未拉取到任务, 结束爬虫")
                    break
                await self._crawl_by_task(task)
            elif execute_type == ExecuteType.PERMANENT:
                if not task:
                    logger.info(f"[{self.get_name()}]未拉取到任务, 休眠1秒后重新拉取任务")
                    await asyncio.sleep(1)
                    continue
                await self._crawl_by_task(task)
        await self.close_session()

    async def _crawl_by_task(self, task):
        pass
